package org.jwt.oauth.config;

import java.util.ArrayList;
import java.util.List;

import org.jwt.oauth.properties.FusionTokenProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

@Configuration
@EnableAuthorizationServer
public class FusionTokenServerConfig extends AuthorizationServerConfigurerAdapter {

	@Autowired
	private FusionTokenProperties tokenConfigProperties;
	@Autowired
	private JwtAccessTokenConverter jwtAccessTokenConverter;
	@Autowired
	private JwtTokenEnhancer jwtTokenEnhancer;

	@Override
	public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
		clients
				// 内村存储
				.inMemory()
				// clientId 配置文件里面的配置就失效
				.withClient(tokenConfigProperties.getUsername())
				// clientSecret 配置文件里面的配置就失效
				.secret(tokenConfigProperties.getPassword())
				// 支持的认证方式
				.authorizedGrantTypes("authorization_code", "client_credentials", "refresh_token", "password",
						"implicit")
				// token有效时间
				.accessTokenValiditySeconds(tokenConfigProperties.getAccessTokenTime())
				// refreshToken的有效时间
				.refreshTokenValiditySeconds(tokenConfigProperties.getRefreshTokenTime()).scopes("all");
	}

	@Override
	public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
		security.tokenKeyAccess("isAuthenticated()");
	}

	@Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
		endpoints.tokenStore(jwtTokenStore());
		endpoints.accessTokenConverter(jwtAccessTokenConverter);
		endpoints.tokenEnhancer(initTokenEnhancerChain()); 
	}

	@Bean
	public TokenStore jwtTokenStore() {
		return new JwtTokenStore(jwtAccessTokenConverter());
	}

	@Bean
	public JwtAccessTokenConverter jwtAccessTokenConverter() {
		JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter() {
			@Override
			public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
				OAuth2AccessToken enhancedToken = super.enhance(accessToken, authentication);
				return enhancedToken;
			}
		};
		jwtAccessTokenConverter.setSigningKey(tokenConfigProperties.getUsername());
		return jwtAccessTokenConverter;
	}

	@Bean
	@ConfigurationProperties("spring.fusion.token")
	@ConditionalOnMissingBean(FusionTokenProperties.class)
	public FusionTokenProperties fusionTokenProperties() {
		return new FusionTokenProperties();
	}

	public TokenEnhancerChain initTokenEnhancerChain() {
		TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
		List<TokenEnhancer> list = new ArrayList<>();
		list.add(jwtTokenEnhancer);
		list.add(jwtAccessTokenConverter);
		tokenEnhancerChain.setTokenEnhancers(list);
		return tokenEnhancerChain;
	}

}
